#include ".\dimanager.h"

extern HINSTANCE hInst;				// holds the instance for this app

int LSTATE = -1;

diManager::diManager(void)
{
	m_lpDI = NULL;
	m_lpDIDevice = NULL;
}

diManager::~diManager(void)
{
	shutdown();
}

/*******************************************************************
* initDirectInput
* Initializes DirectInput for use with a mouse device
*******************************************************************/
bool diManager::initDirectInput(HINSTANCE hInst, HWND wndHandle)
{
	HRESULT hr;

	// Create the DirectInput object. 
    hr = DirectInput8Create(hInst, DIRECTINPUT_VERSION, 
                            IID_IDirectInput8, (void**)&m_lpDI, NULL);  

	if FAILED(hr) 
		return FALSE; 

    // Retrieve a pointer to an IDirectInputDevice8 interface 
    hr = m_lpDI->CreateDevice(GUID_SysMouse, &m_lpDIDevice, NULL); 
	if FAILED(hr)
		return FALSE; 
	
	hr = m_lpDIDevice->SetDataFormat(&c_dfDIMouse); 
	if FAILED(hr)
		return FALSE; 
	
	// Set the cooperative level 
    hr = m_lpDIDevice->SetCooperativeLevel(wndHandle, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); 
    if FAILED(hr) 
        return FALSE; 

    // Get access to the input device. 
    hr = m_lpDIDevice->Acquire(); 
    if FAILED(hr) 
        return FALSE; 

	// Retrieve a pointer to an IDirectInputDevice8 interface 
    hr = m_lpDI->CreateDevice(GUID_SysKeyboard, &m_lpDIDeviceK, NULL); 
	if FAILED(hr)
		return FALSE; 
	
	hr = m_lpDIDeviceK->SetDataFormat(&c_dfDIKeyboard); 
	if FAILED(hr)
		return FALSE; 
	
	// Set the cooperative level 
    hr = m_lpDIDeviceK->SetCooperativeLevel(wndHandle, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND); 
    if FAILED(hr) 
        return FALSE; 

    // Get access to the input device. 
    hr = m_lpDIDeviceK->Acquire(); 
    if FAILED(hr) 
        return FALSE; 

	for(int i = 0; i < 256; i++)
	{
		LastBuffer[i] = 0;
		buffer[i] = 0;
	}

	return true;
}

/*******************************************************************
* shutdown
* Shuts down and releases DirectInput
*******************************************************************/
void diManager::shutdown(void)
{
	if (m_lpDI) 
    { 
        if (m_lpDIDevice) 
        { 
			// Always unacquire device before calling Release(). 
            m_lpDIDevice->Unacquire(); 
            m_lpDIDevice->Release();
            m_lpDIDevice = NULL; 

			// Always unacquire device before calling Release(). 
            m_lpDIDeviceK->Unacquire(); 
            m_lpDIDeviceK->Release();
            m_lpDIDeviceK = NULL; 
        } 
        m_lpDI->Release();
        m_lpDI = NULL; 
    } 
}

/*******************************************************************
* getInput
* Retrieves the current user input
*******************************************************************/
void diManager::getInput(void)
{
	HRESULT hr;

	hr = m_lpDIDevice->GetDeviceState(sizeof(DIMOUSESTATE),(LPVOID)&mouseState); 

	// check the return state to see if the device is still accessible
	if (FAILED ( hr ))
	{
		// try and reacquire the input device
		hr = m_lpDIDevice->Acquire();
		// do a continuous loop until the device is reacquired
	       while( hr == DIERR_INPUTLOST ) 
			hr = m_lpDIDevice->Acquire();
	}	

	hr = m_lpDIDeviceK->GetDeviceState(sizeof(buffer),(LPVOID)&buffer); 

	// check the return state to see if the device is still accessible
	if (FAILED ( hr ))
	{
		// try and reacquire the input device
		hr = m_lpDIDeviceK->Acquire();
		// do a continuous loop until the device is reacquired
	       while( hr == DIERR_INPUTLOST ) 
			hr = m_lpDIDeviceK->Acquire();
	}			
}

/*******************************************************************
* isButtonDown
*******************************************************************/
int diManager::isButtonDown(int which)
{
	return (int)BUTTONDOWN(mouseState, which);
}

bool diManager::isKeyDown(unsigned char which)
{
	while((unsigned char)KEYDOWN(buffer, which))
	{
		return true;
	}
	return false;
}

bool diManager::KeyDownEvent(unsigned char which)
{
	#define REPEAT1 40
	#define REPEAT2 10

	while((unsigned char)DOWNEVENT(buffer, LastBuffer, which))
	{
		return true;
	}
	return false;
}

void diManager::checkBuffers(void)
{
	for(int i = 0; i < 256; i++)
	{
		LastBuffer[i] = buffer[i];
		if(KEYDOWN(buffer,i))
		{
			countBuffer[i]--;
			if(countBuffer[i] == 0)
			{
				countBuffer[i] = REPEAT2;
				LastBuffer[i] = 0;
			}
			else
			{
				countBuffer[i] = REPEAT1;
			}
		}
	}
}

bool diManager::ButtonDownEvent(int which)
{
	if(BUTTONDOWNEVENT(mouseState,lastState,which))
	{
		return true;
	}
	return false;
}

void diManager::chckMouseBuffers(void)
{
	int which = 0;
	lastState = mouseState;
	if(BUTTONDOWN(mouseState, which))
	{
		LSTATE--;
		if(LSTATE == 0)
		{
			LSTATE = REPEAT2;
		}
		else
		{
			LSTATE = REPEAT1;
		}
	}
}
